
from abc import ABCMeta, abstractmethod
import sys, logging, requests, json, time, hmac, hashlib, base64, urllib.parse

logging.basicConfig(
    format = "%(asctime)s %(levelname)s:%(name)s: %(message)s",
    level = logging.INFO,
    datefmt = "%H:%M:%S",
    stream = sys.stderr
)
logger = logging.getLogger(__name__)


class DingRobot(metaclass=ABCMeta):

    def __init__(self, webhooks: list, secrets: list) -> None:
        self._webhooks = webhooks
        self._secrets = secrets
        self._title = None
        self._text = None


    @property
    def text(self):
        return self._text

    def gen_sign(self, timestamp, secret):
        secret_enc = secret.encode('utf-8')
        string_to_sign = f'{timestamp}\n{secret}'
        string_to_sign_enc = string_to_sign.encode('utf-8')
        hmac_code = hmac.new(secret_enc, string_to_sign_enc, digestmod=hashlib.sha256).digest()
        sign = urllib.parse.quote_plus(base64.b64encode(hmac_code))
        return sign

    # 通过钉钉机器人发送信息
    def send_message(self, webhook, timestamp, secret, is_at_all, title_message, text_message):
        sign = self.gen_sign(timestamp, secret)
        headers = {'Content-Type': 'application/json'}
        data = {
            "msgtype": "markdown",
            "markdown": {
                "title": title_message, 
                "text": text_message
                },
            "at": {
                "isAtAll": is_at_all
            }
            }
        signed_url = f"{webhook}&timestamp={timestamp}&sign={sign}"
        try:
            response = requests.post(signed_url, data=json.dumps(data), headers=headers, timeout=8)
        except Exception:
            logger.info("失去响应！")
            return False
        if response.status_code == 200:
            dict_res = response.json()
            if dict_res['errcode'] == 310000:
                logger.info(f"消息发送失败！失败原因：{dict_res['errmsg']}")
                return False
            elif dict_res['errcode'] == 0:
                logger.info("消息发送成功！")
                return True
            return dict_res
        elif response.status_code == 404:
            logger.info("该页面不存在！")
            return False
        else:
            logger.info(f"消息发送失败！{response.status_code}错误")
            return False

    # 创建发送的信息文字
    @abstractmethod
    def gen_message(self):
        self._title = 'hello'
        self._text = 'world'

    # 向不同钉钉群按顺序发送消息
    def to_ding_talk(self):
        self.gen_message()
        if len(self._webhooks) == len(self._secrets):
            for webhook, secret in zip(self._webhooks, self._secrets):
                timestamp = str(round(time.time() * 1000))
                self.send_message(webhook, timestamp, secret, False, self._title, self._text)
        else:
            logger.info(f"请把加签secret添加到secrets.txt!")